package base.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Hashtable;

/**
 * @Author Fizz Pu
 * @Date 2021/4/1 下午11:24
 * @Version 1.0
 * 失之毫厘，缪之千里！
 */

// 动态代理
// 1. 定义接口
// 2. 定义实现类
// 3. 实现InvocatinHandler接口, 重写invoke方法
// 4. 调用Proxy.newInstance方法产生动态代理类

interface Task{
    void doSomething();
    void somethingElse(String arg);
}


class RealTask implements Task{
    @Override
    public void doSomething() {
        System.out.println("do something");
    }

    @Override
    public void somethingElse(String arg) {
        System.out.println("something else" + arg);
    }
}


public class SimpleDynamicProxy implements InvocationHandler {
    private Task task;

    private Hashtable<String, Integer> counterMap;

    public SimpleDynamicProxy(Task task, Hashtable<String, Integer> counterMap) {
        this.task = task;
        this.counterMap = counterMap;
    }

    public Hashtable<String, Integer> getCounterMap(){
        return counterMap;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理方法" + method.getName());
        // System.out.println("代理对象" + proxy); 递归调用
        // Object result = method.invoke(proxy, args); 递归调用
        Object result = method.invoke(task, args);

        String functionName = method.getName();
        if(!counterMap.containsKey(functionName)){
            counterMap.put(functionName, 0);
        }
        counterMap.put(functionName, counterMap.get(functionName) + 1);

        return result;
    }

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        Hashtable<String, Integer> counterMap = new Hashtable<>();
        Task task = (Task) Proxy.newProxyInstance(Task.class.getClassLoader(),
                new Class[]{Task.class}, new SimpleDynamicProxy(new RealTask(), counterMap));

        task.somethingElse("something");
        task.somethingElse("hello");
        task.toString();
        task.doSomething();
        task.toString();

        System.out.println(counterMap);
    }
}

